package com.demo.zhlg.service.impl;

import com.demo.zhlg.entity.TaskApplications;
import com.demo.zhlg.entity.TaskOrders;
import com.demo.zhlg.mapper.TaskApplicationsMapper;
import com.demo.zhlg.mapper.TaskOrdersMapper;
import com.demo.zhlg.util.Result;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.demo.zhlg.entity.Tasks;
import com.demo.zhlg.mapper.TasksMapper;
import com.demo.zhlg.service.TasksService;
import org.apache.ibatis.jdbc.Null;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.config.Task;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.sqlite.date.DateFormatUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.demo.zhlg.entity.table.TasksTableDef.TASKS;
import static com.demo.zhlg.entity.table.TaskCategoriesTableDef.TASK_CATEGORIES;
import static com.demo.zhlg.entity.table.TaskApplicationsTableDef.TASK_APPLICATIONS;
import static com.demo.zhlg.entity.table.TaskOrdersTableDef.TASK_ORDERS;

/**
 *  服务层实现。
 *
 * @author lenovo
 * @since 2025-04-26
 */
@Service
public class TasksServiceImpl extends ServiceImpl<TasksMapper, Tasks> implements TasksService {
    @Autowired
    private TasksMapper tasksMapper;
    @Autowired
    private TaskApplicationsMapper taskApplicationsMapper;
    @Autowired
    private TaskOrdersMapper taskOrdersMapper;

    private int getUserId() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        return loginUser.getUser().getUserId();
    }

    @Override
    public Object increaseViewCount(Integer taskId) {
        Tasks task = tasksMapper.selectOneById(taskId);
        task.setViewCount(task.getViewCount() + 1);
        return Result.success(tasksMapper.update(task));
    }

    @Override
    public Object applyTask(Integer taskId) {
        TaskApplications taskApplication = new TaskApplications();
        taskApplication.setTaskId(taskId);
        taskApplication.setApplicantId(getUserId());
        taskApplication.setApplicationStatus(0);
        taskApplication.setCreateTime(DateFormatUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss"));
        taskApplication.setUpdateTime(DateFormatUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss"));
        Tasks task = tasksMapper.selectOneById(taskId);
        task.setApplyCount(task.getApplyCount() + 1);
        tasksMapper.update(task);
        return Result.success(taskApplicationsMapper.insert(taskApplication));
    }

    @Override
    public Object getSimilarTasks(Integer taskId) {
        Tasks task = tasksMapper.selectOneById(taskId);
        return Result.success(tasksMapper
                .selectListByQuery(new QueryWrapper()
                        .where(TASKS.TASK_CATEGORY_ID.eq(task.getTaskCategoryId())).limit(4)));
    }

    @Override
    public Object searchTasks(String keyword) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper
                .select(TASKS.ALL_COLUMNS)
                .from(TASKS, TASK_CATEGORIES)
                .where(
                        TASKS.TASK_CATEGORY_ID.eq(TASK_CATEGORIES.CATEGORY_ID)
                                .and(TASKS.TASK_ADDRESS.like(keyword)
                                        .or(TASKS.TASK_DESCRIPTION.like(keyword))
                                        .or(TASK_CATEGORIES.CATEGORY_NAME.like(keyword)))
                                        .or(TASKS.WORK_HOURS.like(keyword))

                );
        return Result.success(tasksMapper.selectListByQuery(queryWrapper));
    }

    @Override
    public Object publishTask(Tasks task) {
        task.setPublisherId(getUserId());
        task.setTaskStatus(0);
        task.setCreateTime(DateFormatUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss"));
        task.setUpdateTime(DateFormatUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss"));
        return Result.success(tasksMapper.insert(task));
    }

    @Override
    public Object getMyPublishedTasks() {
        return Result.success(tasksMapper.selectListByQuery(
                new QueryWrapper()
                        .where(TASKS.PUBLISHER_ID.eq(getUserId()))
                        .orderBy(TASKS.TASK_ID, false)));
    }

    @Override
    public Object getMyAppliedTasks() {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper
                .select(TASKS.ALL_COLUMNS)
                .from(TASKS, TASK_APPLICATIONS)
                .where(TASKS.TASK_ID.eq(TASK_APPLICATIONS.TASK_ID))
                .and(TASK_APPLICATIONS.APPLICANT_ID.eq(getUserId()))
                .orderBy(TASKS.TASK_ID, false);
        return Result.success(tasksMapper.selectListByQuery(queryWrapper));
    }

    @Override
    public Object cancelApply(Integer taskId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper
                .where(TASK_APPLICATIONS.APPLICANT_ID.eq(getUserId()))
                .and(TASK_APPLICATIONS.TASK_ID.eq(taskId));
        Tasks task = tasksMapper.selectOneById(taskId);
        task.setApplyCount(task.getApplyCount() - 1);
        tasksMapper.update(task);
        return Result.success(taskApplicationsMapper.deleteByQuery(queryWrapper));
    }

    @Override
    public Object cancelTask(Integer taskId) {
        return Result.success(tasksMapper.deleteById(taskId));
    }

    @Override
    public Object generateOrder(Integer taskId) {
        Tasks task = tasksMapper.selectOneById(taskId);
        TaskApplications taskApplication = taskApplicationsMapper
                .selectOneByQuery(new QueryWrapper()
                        .where(TASK_APPLICATIONS.TASK_ID.eq(taskId))
                        .limit(1));
        TaskOrders taskOrder = new TaskOrders();
        double totalFee = 0.0;
        if(task.getSalaryType().equals("元/天")){
            totalFee = task.getSalary();
        } else {
            totalFee = task.getSalary() * task.getWorkHours();
        }
        taskOrder.setTaskId(taskId);
        taskOrder.setEmployerId(task.getPublisherId());
        taskOrder.setWorkerId(taskApplication.getApplicantId());
        taskOrder.setApplicationId(taskApplication.getApplicationId());
        taskOrder.setOrderAmount(totalFee);
        taskOrder.setPlatformFee(totalFee * 0.1);
        taskOrder.setActualAmount(totalFee * 1.1);
        taskOrder.setOrderStatus(0);
        taskOrder.setPaymentStatus(0);
        taskOrder.setStartTime(DateFormatUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss"));
        taskOrder.setCreateTime(DateFormatUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss"));
        taskOrder.setUpdateTime(DateFormatUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss"));
        task.setTaskStatus(2);
        tasksMapper.update(task);
        taskOrdersMapper.insert(taskOrder);
        return Result.success(taskOrdersMapper.selectOneByQuery(
                new QueryWrapper()
                        .select(TASK_ORDERS.ORDER_ID)
                        .where(TASK_ORDERS.TASK_ID.eq(taskId))
        ));
    }

    @Override
    public Object isPublisher(Integer taskId) {
        return Result.success(tasksMapper.selectOneById(taskId).getPublisherId() - getUserId() == 0);
    }

    @Override
    public Object isAlreadyApplied(Integer taskId) {
        return Result.success(taskApplicationsMapper.selectListByQuery(
                new QueryWrapper()
                        .where(TASK_APPLICATIONS.APPLICANT_ID.eq(getUserId()).and(TASK_APPLICATIONS.TASK_ID.eq(taskId)))
        ));
    }

    @Override
    public Object getTaskList() {
        return Result.success(tasksMapper.selectListByQuery(
                new QueryWrapper()
                        .orderBy(TASKS.TASK_ID, false)
        ));
    }

    @Override
    public Object getTaskByCategory(Integer categoryId) {
        return Result.success(tasksMapper.selectListByQuery(
                new QueryWrapper()
                        .where(TASKS.TASK_CATEGORY_ID.eq(categoryId))
        ));
    }

    @Override
    public Object updateTaskExpiration() {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String currentTime = sdf.format(new Date());

            QueryWrapper queryWrapper = QueryWrapper.create()
                    .where("task_status = 0")
                    .and("end_time < ?", currentTime);

            Tasks task = new Tasks();
            task.setTaskStatus(-2);

            int updatedCount = tasksMapper.updateByQuery(task, queryWrapper);

            return Result.success(updatedCount);

        } catch (Exception e) {
            return Result.fail("更新任务过期状态失败: " + e.getMessage());
        }
    }
}
